﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using GDocUploader.Communication;
using Google.GData.Client;
using Google.GData.Documents;
using Google.GData.Extensions;
using Google.Documents;
using System.IO;
using System.Management;
using System.Globalization;
using System.Collections;
using System.Net;
using System.Net.NetworkInformation;
using System.Diagnostics;

namespace GDocUploader
{
    public partial class frmUploader : Form
    {
        public static DocumentsService ServGen { set; get; }
        private SortedList<int, Gdoc> Gdocs = new SortedList<int, Gdoc>();
        private String Username;
        private String Password;
        private string SelectedImagePath;
        private GDocUploader.Communication.Operations Do = new Operations();
        private delegate void Processus1(String chemin);
        private delegate void processus2(String Chein, String Pat);
        private delegate void Processus3();
        private bool islogedin = false;


        Feed<Document> Fed = null;
        public struct Gdoc
        {
            public String DocId;
            public String DocIdUrl;
            public String libelle;
            public Boolean IsFolder;
            public String ParentIdUrl;
            public String ParentLibelle;

            public Gdoc(String id, String UrL, String Lib, Boolean IsFold, String ParIdUrl, String ParLib)
            {
                this.DocId = id;
                this.DocIdUrl = UrL;
                this.libelle = Lib;
                this.IsFolder = IsFold;
                this.ParentIdUrl = ParIdUrl;
                this.ParentLibelle = ParLib;
            }



        }
        public ToolTip Tp = new ToolTip();


        /// <summary>
        /// Initialisation du Formulaire de demarrage
        /// </summary>
        public frmUploader()
        {
            InitializeComponent();
            if (!EventLog.SourceExists("GDOCUploader"))
                EventLog.CreateEventSource("GDOCUploader", "Application");
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Text = "Formulaire d'Upload des fichiers et répertoires vers compte Google";
            Tp.SetToolTip(this.button1, "Se connecter au compte Google documents");
            Tp.SetToolTip(this.Btndeconn, "Se déconnecter");
            Tp.SetToolTip(this.button3, "Afficher A Propos");
            Tp.SetToolTip(this.button4, "Actualisation de la liste des fichiers et des dossiers locaux");//lst local
            Tp.SetToolTip(this.button5, "Actualisation de la liste des fichiers et des dossiers sous le compte Google");//lst google
            Tp.SetToolTip(this.textBox1, "Espace de saisie du nom d'utilisateur");
            Tp.SetToolTip(this.textBox2, "Espace de saisie du mot de passe");
            Tp.SetToolTip(this.BtnUpload, "Bouton Upload" + Environment .NewLine + "Upload un Object vers un autre");
            
        }

     

        /// <summary>
        /// Démarrage du formulaire
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            this.Focus();
            Btndeconn.Enabled = false;
            BtnUpload.Enabled = false;
            Chr_Lst1();
        }

        /// <summary>
        /// confirmation du fermeture du formulaire
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
           
            if (MessageBox.Show("Voulez Vous Vraiment Quitter  ?", Application.CompanyName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                Environment.Exit(0);
        }

        /// <summary>
        /// Obtenir la liste des documents dans un répertoire spécifique du compte utilisateur
        /// </summary>
        /// <param name="service">Document Service utiliser pour la connexion</param>
        /// <param name="folder">Nom du répertoire contenant les fichiers à importer</param>
        /// <param name="email">l'e-mail de l'utilisateur ou nom d'utilisateur</param>
        /// <returns>Liste de document</returns>
        public DocumentsFeed RetrieveDocsInFolder(DocumentsService service, string folder, string email)
        {
            AtomCategory folderCategory = new AtomCategory(folder, new AtomUri("http://schemas.google.com/docs/2007/folders/" + email));
            QueryCategory folderQueryCategory = new QueryCategory(folderCategory);
            DocumentsListQuery query = new DocumentsListQuery();
            query.Categories.Add(folderQueryCategory);
            return service.Query(query);
        }

        /// <summary>
        /// Télécharger une Arborescence vers un compte Google
        /// </summary>
        /// <param name="chemin">Chemin de l'arborescence</param>
        public void Upload(String chemin)
        {
            new Declacheur(chemin);
          
        }

        /// <summary>
        /// Télécharger une Arborescence vers un compte Google
        /// </summary>
        /// <param name="Chemin">Chemin de l'arborescence</param>
        /// <param name="Path_F">Chemin sous Google ou enregistrer l'arborescence</param>
        public void Upload(String Chemin, String Path_F)
        {
            new Declacheur(Chemin, Path_F);
         
        }

        /// <summary>
        /// Charge La liste des Lecteurs Locaux
        /// </summary>
        void Chr_Lst1()
        {
            this.Lstlocal.Nodes.Clear();
            foreach (string s in Directory.GetLogicalDrives())
            {
                TreeNode item = new TreeNode();
                item.Text = s;
                item.Tag = s;
                item.ImageIndex = 0;
                Lstlocal.Nodes.Add(item);
            }
        }

        /// <summary>
        /// Charge des Fichiers et répertoire sous Google
        /// </summary>
        /// <param name="id">Url du dossier parent</param>
        /// <param name="node">node parent dans le TreeView</param>
        void Filter(String id, TreeNode node)
        {
            for (int i = 0; i < Gdocs.Count; i++)
            {
                if (Gdocs[i].ParentIdUrl == id)
                {
                    TreeNode te = new TreeNode();
                    te.Text = Gdocs[i].libelle;
                    if (Gdocs[i].IsFolder)
                    {
                        te.StateImageIndex = 1;
                        te.SelectedImageIndex = 1;
                        te.ImageIndex = 1;
                    }
                    else
                    {
                        te.StateImageIndex = 2;
                        te.SelectedImageIndex = 2;
                        te.ImageIndex = 2;

                    }
                    node.Nodes.Add(te);
                    if (Gdocs[i].IsFolder)
                    {
                        Filter(Gdocs[i].DocIdUrl, te);
                    }
                }
            }
        }

        private delegate void Process4(TreeNode te);

        /// <summary>
        /// Charge des Fichiers et répertoire sous Google
        /// </summary>
        void Chr_LstGoogle()
        {
            Gdocs = new SortedList<int, Gdoc>();
            LstGoogle.Nodes.Clear();
           
            DocumentsRequest rs = new DocumentsRequest(new RequestSettings("GDocUploader", frmUploader.ServGen.Credentials));
            Fed = rs.GetEverything();
            
            int compteur = 0;
            Gdoc G;
            foreach (Document D in Fed.Entries)
            {
                if (D.ParentFolders.Count == 0)
                {
                    G = new Gdoc(D.DocumentId, D.Id, D.Title, D.DocumentEntry.IsFolder, null, null);
                    Gdocs.Add(compteur, G);
                    compteur++;
                }

                else
                {
                    for (int k = 0; k < D.ParentFolders.Count; k++)
                    {
                        G = new Gdoc(D.DocumentId, D.Id, D.Title, D.DocumentEntry.IsFolder, D.ParentFolders[k], D.DocumentEntry.ParentFolders[k].Title);
                        Gdocs.Add(compteur, G);
                        compteur++;
                    }
                }
            }
           
             rs = new DocumentsRequest(new RequestSettings("GDocUploader", frmUploader.ServGen.Credentials));
            Fed = rs.GetEverything();
            
            foreach (Document D in Fed.Entries)
            {

                if (D.DocumentEntry.IsFolder)
                {
                    if ((D.ParentFolders.Count == 0) && (D.DocumentEntry.IsFolder))
                    {
                        TreeNode Te = new TreeNode();
                        Te.Text = D.Title;
                        if (D.DocumentEntry.IsFolder)
                        {
                            Te.StateImageIndex = 1;
                            Te.SelectedImageIndex = 1;
                            Te.ImageIndex = 1;
                        }
                        else
                        {
                            Te.StateImageIndex = 2;
                            Te.SelectedImageIndex = 2;
                            Te.ImageIndex = 2;

                        }
                       LstGoogle.Nodes.Add(Te);
                      Filter(D.Id, Te);

                    }
                }
                else if ((D.ParentFolders.Count == 0) && (!D.DocumentEntry.IsFolder))
                {
                    TreeNode Te = new TreeNode();
                    Te.Text = D.Title;
                    Te.StateImageIndex = 2;
                    Te.SelectedImageIndex = 2;
                    Te.ImageIndex = 2;
                    LstGoogle.Nodes.Add(Te);
                }

            }


        }

        /// <summary>
        /// Test de validité des paramètres
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            
            if (this.textBox1.Text.Length == 0)
            {
                this.TxtStatus.Text = "Veuillez Saisir Votre Email";
            }
            else if (this.textBox2.Text.Length == 0)
            {
                this.TxtStatus.Text = "Veuillez Saisir Votre Mot de Passe";
            }
            else
            {
                this.Username = this.textBox1.Text;
                this.Password = this.textBox2.Text;
                Authentification.username = this.Username;
                Authentification.password = this.Password;

                if (!Authentification.login())
                    MessageBox.Show("Coordonnées Erronées");
                else
                {
                    BtnUpload.Enabled = true;
                    this.Btndeconn.Enabled = true;
                    this.button1.Enabled = false;
                    this.textBox1.Enabled = false;
                    this.textBox2.Enabled = false;
                    Processus3 P3 = new Processus3(Chr_LstGoogle);
                    this.BeginInvoke(P3);
                    islogedin = true;
                    this.TxtStatus.Text = "Connecté";

                }
            }
        }


        /// <summary>
        /// démarrage d'envoie de l'arborescence
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnUpload_Click(object sender, EventArgs e)
        {
            
             
         
          
            string chaine = "";
            try
            {
                chaine = LstGoogle.SelectedNode.Text.ToString();
            
           

            }
            catch
            {
                chaine = "";
               
         
               
            }
            try
            {
                SelectedImagePath = Lstlocal.SelectedNode.FullPath;
             
            }
            catch
            {
                SelectedImagePath = "";
          
            }


            if (SelectedImagePath.Length > 0)
            {
                if (chaine.Length == 0)
                {
                
               

 
                    Processus1 P1 = new Processus1(Upload);
                    IAsyncResult R1 = BeginInvoke(P1,new string[]{SelectedImagePath});
                 
                    this.BeginInvoke(new Processus3(Chr_LstGoogle));

               

                     
                 
                    this.BeginInvoke(new Processus3(Chr_Lst1));
                }
                else
                {
                    processus2 P2 = new processus2(Upload);
                    IAsyncResult R2 = BeginInvoke(P2,new string[]{SelectedImagePath, chaine});
                
                  

                    this.BeginInvoke(new Processus3(Chr_LstGoogle));
              


                 

                    this.BeginInvoke(new Processus3(Chr_Lst1));

                 
           
                }
            }
        }

       void CallbackMethod(IAsyncResult result)
        {
            Chr_Lst1();
           
            Chr_LstGoogle();
          
        }
        /// <summary>
        /// Chargement des élèments sous une node du treeview
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Lstlocal_AfterSelect(object sender, TreeViewEventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            TreeNode nodeCurrent = e.Node;
            nodeCurrent.Nodes.Clear();
            PopulateDirectory(nodeCurrent, nodeCurrent.Nodes);
            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// Obtient le chemin complet formaté d'un document
        /// </summary>
        /// <param name="stringPath">Path du document</param>
        /// <returns></returns>
        protected string GetPathName(string stringPath)
        {
            string[] stringSplit = stringPath.Split('\\');
            int _maxIndex = stringSplit.Length;
            return stringSplit[_maxIndex - 1];
        }

        /// <summary>
        /// Charger la liste des répertoires fils d'un répertoire sous forme des nodes
        /// </summary>
        /// <param name="nodeCurrent"></param>
        /// <param name="nodeCurrentCollection"></param>
        protected void PopulateDirectory(TreeNode nodeCurrent, TreeNodeCollection nodeCurrentCollection)
        {
            TreeNode nodeDir;
            int imageIndex = 1;
            int selectIndex = 1;
            if (nodeCurrent.SelectedImageIndex != 0)
            {
                try
                {
                    PopulateFiles(nodeCurrent);
                    string[] stringDirectories = Directory.GetDirectories(getFullPath(nodeCurrent.FullPath));
                    string stringFullPath = "";
                    string stringPathName = "";
                    foreach (string stringDir in stringDirectories)
                    {
                        stringFullPath = stringDir;
                        stringPathName = GetPathName(stringFullPath);
                        nodeDir = new TreeNode(stringPathName.ToString(), imageIndex, selectIndex);
                        nodeDir.SelectedImageIndex = 1;
                        nodeDir.Tag = getFullPath(nodeCurrent.FullPath);
                        nodeCurrentCollection.Add(nodeDir);
                    }
                }
                catch { }
            }
        }

        /// <summary>
        /// Charger la liste des fichiers fils d'un répertoire sous forme des nodes
        /// </summary>
        /// <param name="nodeCurrent"></param>
        protected void PopulateFiles(TreeNode nodeCurrent)
        {
            if (nodeCurrent.SelectedImageIndex != 0)
            {
                try
                {
                    string[] stringFiles = Directory.GetFiles(getFullPath(nodeCurrent.FullPath));
                    string stringFileName = "";
                    DateTime dtCreateDate, dtModifyDate;
                    Int64 lFileSize = 0;
                    foreach (string stringFile in stringFiles)
                    {
                        stringFileName = stringFile;
                        FileInfo objFileSize = new FileInfo(stringFileName);
                        lFileSize = objFileSize.Length;
                        dtCreateDate = objFileSize.CreationTime;
                        dtModifyDate = objFileSize.LastWriteTime;
                        FileInfo inf = new FileInfo(stringFile);
                        TreeNode n = new TreeNode(inf.Name, 2, 2);
                        n.Tag = inf;
                        nodeCurrent.Nodes.Add(n);
                    }
                }
                catch
                {

                }
            }
        }

        /// <summary>
        /// Obtient le chemin complet formaté d'un document
        /// </summary>
        /// <param name="stringPath">Path du document</param>
        /// <returns></returns>
        protected string getFullPath(string stringPath)
        {
            string stringParse = "";
            stringParse = stringPath.Replace("My Computer\\", "");
            return stringParse;
        }

        /// <summary>
        /// Obtient la liste des disques logiques du système
        /// </summary>
        /// <returns>List des ManagementObject</returns>
        protected ManagementObjectCollection getDrives()
        {
            ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * From Win32_LogicalDisk ");
            ManagementObjectCollection queryCollection = query.Get();
            return queryCollection;
        }

        /// <summary>
        /// Ferme la session utilisateur
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btndeconn_Click(object sender, EventArgs e)
        {
            this.BtnUpload.Enabled = false;
            this.button1.Enabled = true;
            this.Btndeconn.Enabled = false;
            this.textBox1.Enabled = true;
            this.textBox2.Enabled = true;
            this.TxtStatus.Text = "Non Connecté";
            this.LstGoogle.Nodes.Clear();
            Chr_Lst1();
            this.textBox1.Clear();
            this.textBox2.Clear();
            islogedin = false;
        }

        /// <summary>
        /// Envoie d'une arborescence sous une autre dans un compte Google
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Lstlocal_ItemDrag(object sender, ItemDragEventArgs e)
        {

            Clipboard.SetData(DataFormats.Text, getFullPath(((TreeNode)e.Item).FullPath));
            DoDragDrop((TreeNode)e.Item, DragDropEffects.Copy);

        }

        /// <summary>
        ///  Envoie d'une arborescence sous une autre dans un compte Google
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Lstlocal_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        /// <summary>
        /// Affichage de A Propos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            A_Propos P = new A_Propos();
            P.ShowDialog();
        }

        /// <summary>
        /// Envoie d'une arborescence sous une autre dans un compte Google
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LstGoogle_DragDrop(object sender, DragEventArgs e)
        {
            DateTime Dte = DateTime.Now;
         

          
            if (this.textBox1.Enabled == true) MessageBox.Show("Please Login In ");
            else
            {
                String[] DATAs = (String[])e.Data.GetData(DataFormats.FileDrop);
                if (DATAs == null) DATAs = new String[] { Clipboard.GetText() };
                if (DATAs == null) DATAs = new String[] { (String)Clipboard.GetData("text") };
                foreach (String Ss in DATAs)
                {
                    string chaine = "";
                    try
                    {
                        chaine = LstGoogle.SelectedNode.FullPath;

                    
                      
                    }
                    catch
                    {
                        chaine = "";
                       
       
                    }
                        if (chaine.Length == 0)
                        {
                            Processus1 P1 = new Processus1(Upload);
                          
                            
                            IAsyncResult Ar = BeginInvoke(P1, new string[] { Ss });
                          
                           
                            this.BeginInvoke(new Processus3(Chr_LstGoogle));
                        }
                        else
                        {
                            processus2 P2 = new processus2(Upload);
                          

                          
                            IAsyncResult Ar = BeginInvoke(P2,new string[]{ Ss,chaine});
                        

                          
                            this.BeginInvoke(new Processus3(Chr_LstGoogle));
                        }
                }
            }

        }

        private void LstGoogle_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (!islogedin)
            {
                MessageBox.Show("Non connecté");
                return;
            }
            Chr_Lst1();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (!islogedin)
            {
                MessageBox.Show("Non connecté");
                return;
            }
            Chr_LstGoogle();
        }

        private void afficherLesErreursToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Operations.GetRapport());
        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {

        }

      
    }
}
